// GCStock.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <afxinet.h>
#include "GCStock.h"

using namespace std;

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

void removeTags(CString& data,CStringArray& array,CString &timeStamp);
CString removeTag(CString& data, CString tag = _T(""));
int findLMatch(CString& data, int idx);
int findRMatch(CString& data, int idx);
CString getTag(CString& data,int begin,int end, BOOL bEnd = FALSE);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
    {
        // TODO: code your application's behavior here.
        CString strHello;
        strHello.LoadString(IDS_HELLO);
        cout << (LPCTSTR)strHello << endl;
        
        CInternetSession*   Session   =   new   CInternetSession(); 
        CHttpFile*   HTTPFile; 

        
        CString line;
        // Boolean to identify whether the table datatbl has been reached for current session
        BOOL bIsTable = FALSE;
        CString curTimeStamp;
        CString latestRetrTime = _T("");
        while(TRUE)
        {
            HTTPFile   =   (CHttpFile*)Session->OpenURL("http://vip.stock.finance.sina.com.cn/quotes_service/view/vMS_tradedetail.php?symbol=sz002202"); 
            ASSERT(HTTPFile);
            //Initialize bIsTable and tempStamp
            bIsTable = FALSE;
            CString tempStamp = "";

            cout << "Start to get data!!!!!!"<<endl;
            while(HTTPFile->ReadString(line))
            {   
                if(-1 != line.Find(_T("<table class=\"datatbl\" id=\"datatbl\">")))
                {
                    bIsTable = TRUE;
                }
                if(bIsTable)
                {
                    int begin = line.Find(_T("<tr"));
                    int end = line.Find(_T("</tr>"));
                    //             TRACE("begin is %d\n",begin);
                    //             TRACE("end is %d\n",end);
                    
                    if(begin != -1 &&
                        end > 0)
                    {
                        // remove <tr...>...</tr>
                        begin = line.Find(_T(">"));
                        // Store current line without the beginning tag and end tag
                        CString chgLine = line.Mid(begin + 1, end - begin - 1);
                        //Store this line in an array
                        CStringArray array;
                        removeTags(chgLine,array,curTimeStamp);
                        cout<<endl;
                        //If it is the first record of current retrieve, save the timestamp
                        if(tempStamp == "" )
                        {
                            tempStamp = curTimeStamp; 
                        }
                        //If the timestamp of current retrieve is before the latestRetrTime, stop to retrieve
                        if(curTimeStamp <= latestRetrTime )
                        {
                            cout<< "Old data passed" <<endl;
                              break;
                        }
                        // update array to database
                    }    
                }
                
            }
            //Update latestRetrTime
            latestRetrTime = tempStamp;
            HTTPFile->Close();
            delete HTTPFile;
            HTTPFile = NULL;
            //Session->Close();
            Sleep(100);
        }
        system("pause");
    }

	return nRetCode;
}

/////////////////////////////////////////////
// removeTags
// purpose	:   get value in html context one by one
// input	:   data:   html context
//              
// output	:   data: context removed tag
//              array:  store values
// return	:   void
//
/////////////////////////////////////////////
void removeTags(CString& data,CStringArray& array,CString &timeStamp)
{
    BOOL bRecord = FALSE;
    while(data.GetLength()>0)
    {
        
        CString value = removeTag(data/*, data.Mid(lMatch + 1,rMatch - 1)*/);
        
        cout<<LPCTSTR(value)<<"\t";
        if(FALSE == bRecord)
        {
            timeStamp = value;
            bRecord = TRUE;
        }
        array.Add(value); 
        
    }
}

/////////////////////////////////////////////
// removeTag
// purpose	:
// input	:
// output	:
// return	:
//
/////////////////////////////////////////////
CString removeTag(CString& data,CString tag)
{
    int begin = data.Find(_T("<"));
    int end = data.Find(_T("</"),begin);
    int rMatch1, rMatch2;
    CString value = "";
    CString beginTag = _T("");
    CString endTag = _T("");

    if (begin != -1 && end != -1)
    {
        rMatch1 = findRMatch(data,begin);
        beginTag = getTag(data,begin,rMatch1);
        while(TRUE)
        {
            rMatch2 = findRMatch(data,end);
            endTag = getTag(data,end,rMatch2,TRUE);

            if(beginTag == endTag)
            {
                value = removeTag(data.Mid(rMatch1 + 1, end - rMatch1 - 1));
                break;
            }
            else
            {
                end = data.Find(_T("</"),end + 1);
            }
            
        }
    }
    else
    {
        value = data;
    }
    data = data.Mid(rMatch2 + 1);
    return value;
}

/////////////////////////////////////////////
// findRMatch
// purpose	:
// input	:
// output	:
// return	:
//
/////////////////////////////////////////////
int findRMatch(CString& data, int idx)
{
    return data.Find(_T(">"),idx);
}

/////////////////////////////////////////////
// findLMatch
// purpose	:
// input	:
// output	:
// return	:
//
/////////////////////////////////////////////
int findLMatch(CString& data, int idx)
{
    return data.Find(_T("<"),idx);
}

/////////////////////////////////////////////
// getTag
// purpose	:
// input	:
// output	:
// return	:
//
/////////////////////////////////////////////
CString getTag(CString& data,int begin,int end, BOOL bEnd)
{
    int blank = data.Find(_T(" "),begin);
    int first = bEnd?begin + 2:begin + 1;
    if (blank >= 0 && blank < end)
    {
        return data.Mid(first, blank - first);
    }
    return data.Mid(first, end - first);
}